home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir41 / tsrsrc35.zip / XMS.PAS < prev   
Pascal/Delphi Source File  |  1993-10-21  |  10KB  |  390 lines

  1. {**************************************************************************
  2. *   XMS - unit of XMS functions                                           *
  3. *   Copyright (c) 1991,1993 Kim Kokkonen, TurboPower Software.            *
  4. *   May be freely distributed and used but not sold except by permission. *
  5. *                                                                         *
  6. *   Version 3.0 9/24/91                                                   *
  7. *     first release                                                       *
  8. *   Version 3.1 11/4/91                                                   *
  9. *     no change                                                           *
  10. *   Version 3.2 11/22/91                                                  *
  11. *     add AllocateUmbMem, FreeUmbMem functions                            *
  12. *   Version 3.3 1/8/92                                                    *
  13. *     no change                                                           *
  14. *   Version 3.4 2/14/92                                                   *
  15. *     fix unreported bug in GetMem call in function GetXmsHandles         *
  16. *     add AllocateHma and FreeHma functions                               *
  17. *   Version 3.5 10/18/93                                                  *
  18. *     no change                                                           *
  19. ***************************************************************************}
  20.  
  21. {$R-,S-,I-,V-,B-,F-,A-,E-,N-,G-,X-}
  22.  
  23. unit Xms;
  24.   {-XMS functions needed for TSR Utilities}
  25.  
  26. interface
  27.  
  28. const
  29.   ExhaustiveXms : Boolean = False;
  30.  
  31. type
  32.   XmsHandleRecord =
  33.   record
  34.     Handle : Word;
  35.     NumPages : Word;
  36.   end;
  37.   XmsHandles = array[1..16380] of XmsHandleRecord;
  38.   XmsHandlesPtr = ^XmsHandles;
  39.  
  40. function XmsInstalled : Boolean;
  41.   {-Returns True if XMS memory manager installed}
  42.  
  43. function QueryFreeExtMem(var TotalFree, LargestBlock : Word) : Byte;
  44.   {-Return info about free XMS (in k bytes)}
  45.  
  46. function GetHandleInfo(XmsHandle : Word;
  47.                        var LockCount    : Byte;
  48.                        var HandlesLeft  : Byte;
  49.                        var BlockSizeInK : Word) : Byte;
  50.   {-Return info about specified Xms handle}
  51.  
  52. function AllocateExtMem(SizeInK : Word; var XmsHandle : Word) : Byte;
  53.   {-Allocate XMS memory}
  54.  
  55. function FreeExtMem(XmsHandle : Word) : Byte;
  56.   {-Free XMS memory}
  57.  
  58. function AllocateUmbMem(SizeInP : Word; var Segment, Size : Word) : Byte;
  59.   {-Allocate UMB memory}
  60.  
  61. function FreeUmbMem(Segment : Word) : Byte;
  62.   {-Deallocate UMB memory}
  63.  
  64. function AllocateHma(SizeInB : Word) : Byte;
  65.   {-Allocate the HMA, requesting SizeInB bytes}
  66.  
  67. function FreeHma : Byte;
  68.   {-Free the HMA}
  69.  
  70. function GetXmsHandles(var XmsPages : XmsHandlesPtr) : Word;
  71.   {-Return number of XMS handles allocated, and pointer to array of handle records}
  72.  
  73. function ExtMemPossible : Boolean;
  74.   {-Return true if raw extended memory is possible}
  75.  
  76. function ExtMemTotalPrim : LongInt;
  77.   {-Returns total number of bytes of extended memory in the system}
  78.  
  79. {=======================================================================}
  80.  
  81. implementation
  82.  
  83. var
  84.   XmsControl       : Pointer;          {ptr to XMS control procedure}
  85.  
  86.   function XmsInstalled : Boolean;
  87.     {-Returns True if XMS memory manager installed}
  88.   begin
  89.     XmsInstalled := (XmsControl <> nil);
  90.   end;
  91.  
  92.   function XmsInstalledPrim : Boolean; assembler;
  93.     {-Returns True if an XMS memory manager is installed}
  94.   asm
  95.     mov ah,$30
  96.     int $21
  97.     cmp al,3
  98.     jae @Check2F
  99.     mov al,0
  100.     jmp @Done
  101. @Check2F:
  102.     mov ax,$4300
  103.     int $2F
  104.     cmp al,$80
  105.     mov al,0
  106.     jne @Done
  107.     inc al
  108. @Done:
  109.   end;
  110.  
  111.   function XmsControlAddr : Pointer; assembler;
  112.     {-Return address of XMS control function}
  113.   asm
  114.     mov ax,$4310
  115.     int $2F
  116.     mov ax,bx
  117.     mov dx,es
  118.   end;
  119.  
  120.   function QueryFreeExtMem(var TotalFree, LargestBlock : Word) : Byte; assembler;
  121.     {-Return info about free XMS}
  122.   asm
  123.     mov ah,$08
  124.     call dword ptr [XmsControl]
  125.     or ax,ax
  126.     jz @Done
  127.     les di,TotalFree
  128.     mov es:[di],dx
  129.     les di,LargestBlock
  130.     mov es:[di],ax
  131.     xor bl,bl
  132. @Done:
  133.     mov al,bl
  134.   end;
  135.  
  136.   function GetHandleInfo(XmsHandle : Word;
  137.                          var LockCount    : Byte;
  138.                          var HandlesLeft  : Byte;
  139.                          var BlockSizeInK : Word) : Byte; assembler;
  140.     {-Return info about specified Xms handle}
  141.   asm
  142.     mov ah,$0E
  143.     mov dx,XmsHandle
  144.     call dword ptr [XmsControl]
  145.     test ax,1
  146.     jz @Done
  147.     les di,LockCount
  148.     mov byte ptr es:[di],bh
  149.     les di,HandlesLeft
  150.     mov byte ptr es:[di],bl
  151.     les di,BlockSizeInK
  152.     mov es:[di],dx
  153.     xor bl,bl
  154. @Done:
  155.     mov al,bl
  156.   end;
  157.  
  158.   function AllocateExtMem(SizeInK : Word; var XmsHandle : Word) : Byte; assembler;
  159.     {-Allocate XMS memory}
  160.   asm
  161.     mov ah,$09
  162.     mov dx,SizeInK
  163.     call dword ptr [XmsControl]
  164.     test ax,1
  165.     jz @Done
  166.     les di,XmsHandle
  167.     mov es:[di],dx
  168.     xor bl,bl
  169. @Done:
  170.     mov al,bl
  171.   end;
  172.  
  173.   function FreeExtMem(XmsHandle : Word) : Byte; assembler;
  174.     {-Free XMS memory}
  175.   asm
  176.     mov ah,$0A
  177.     mov dx,XmsHandle
  178.     call dword ptr [XmsControl]
  179.     test ax,1
  180.     jz @Done
  181.     xor bl,bl
  182. @Done:
  183.     mov al,bl
  184.   end;
  185.  
  186.   function AllocateUmbMem(SizeInP : Word; var Segment, Size : Word) : Byte; assembler;
  187.   asm
  188.     mov ah,$10
  189.     mov dx,SizeInP
  190.     call dword ptr [XmsControl]
  191.     les di,Size
  192.     mov es:[di],dx            {return size of allocated block or largest block}
  193.     test ax,1
  194.     jz @Done
  195.     les di,Segment
  196.     mov es:[di],bx            {return segment}
  197.     xor bl,bl                 {no error}
  198. @Done:
  199.     mov al,bl                 {return error result}
  200.   end;
  201.  
  202.   function FreeUmbMem(Segment : Word) : Byte; assembler;
  203.   asm
  204.     mov ah,$11
  205.     mov dx,Segment
  206.     call dword ptr [XmsControl]
  207.     test ax,1
  208.     jz @Done
  209.     xor bl,bl
  210. @Done:
  211.     mov al,bl
  212.   end;
  213.  
  214.   function AllocateHma(SizeInB : Word) : Byte; assembler;
  215.   asm
  216.     mov dx,SizeInB
  217.     mov ah,1
  218.     call dword ptr [XmsControl]
  219.     or ax,ax
  220.     jz @Done
  221.     xor bl,bl
  222. @Done:
  223.     mov al,bl
  224.   end;
  225.  
  226.   function FreeHma : Byte; assembler;
  227.   asm
  228.     mov ah,2
  229.     call dword ptr [XmsControl]
  230.     or ax,ax
  231.     jz @Done
  232.     xor bl,bl
  233. @Done:
  234.     mov al,bl
  235.   end;
  236.  
  237.   function GetXmsHandles(var XmsPages : XmsHandlesPtr) : Word;
  238.     {-Return number of XMS handles allocated, and pointer to array of handle records}
  239.   var
  240.     H : Word;
  241.     H0 : Word;
  242.     H1 : Word;
  243.     HCnt : Word;
  244.     FMem : Word;
  245.     FMax : Word;
  246.     HMem : Word;
  247.     LockCount : Byte;
  248.     HandlesLeft : Byte;
  249.     Delta : Integer;
  250.     Status : Byte;
  251.     Done : Boolean;
  252.  
  253.     procedure ExhaustiveSearchHandles(var Handles : Word; XmsPages : XmsHandlesPtr);
  254.       {-Search handles exhaustively}
  255.     var
  256.       H : Word;
  257.       HCnt : Word;
  258.     begin
  259.       HCnt := 0;
  260.       for H := 0 to 65535 do
  261.         if GetHandleInfo(H, LockCount, HandlesLeft, HMem) = 0 then begin
  262.           inc(HCnt);
  263.           if XmsPages <> nil then
  264.             with XmsPages^[HCnt] do begin
  265.               Handle := H;
  266.               NumPages := HMem;
  267.             end;
  268.         end;
  269.       Handles := HCnt;
  270.     end;
  271.  
  272.   begin
  273.     GetXmsHandles := 0;
  274.  
  275.     Status := QueryFreeExtMem(FMem, FMax);
  276.     if Status = $A0 then begin
  277.       FMem := 0;
  278.       FMax := 0;
  279.     end else if Status <> 0 then
  280.       Exit;
  281.  
  282.     if ExhaustiveXms then begin
  283.       {Search all 64K XMS handles for valid ones}
  284.       HCnt := 0;
  285.       ExhaustiveSearchHandles(HCnt, nil);
  286.       if HCnt <> 0 then begin
  287.         GetMem(XmsPages, HCnt*SizeOf(XmsHandleRecord));
  288.         ExhaustiveSearchHandles(HCnt, XmsPages);
  289.         GetXmsHandles := HCnt;
  290.       end;
  291.  
  292.     end else begin
  293.       {Heuristic algorithm to find used handles quickly}
  294.  
  295.       {Allocate two dummy handles}
  296.       if FMem > 1 then
  297.         HMem := 1
  298.       else
  299.         HMem := 0;
  300.       Status := AllocateExtMem(HMem, H0);
  301.       if Status <> 0 then
  302.         Exit;
  303.       Status := AllocateExtMem(HMem, H1);
  304.       if Status <> 0 then begin
  305.         {Deallocate dummy handle}
  306.         Status := FreeExtMem(H0);
  307.         Exit;
  308.       end;
  309.       Delta := H1-H0;
  310.       {Deallocate one dummy}
  311.       Status := FreeExtMem(H1);
  312.  
  313.       {Trace back through valid handles, counting them}
  314.       HCnt := 0;
  315.       H1 := H0;
  316.       repeat
  317.         Status := GetHandleInfo(H1, LockCount, HandlesLeft, HMem);
  318.         Done := (Status <> 0);
  319.         if not Done then begin
  320.           dec(H1, Delta);
  321.           inc(HCnt);
  322.         end;
  323.       until Done;
  324.  
  325.       if HCnt > 1 then begin
  326.         dec(HCnt);
  327.         GetMem(XmsPages, HCnt*SizeOf(XmsHandleRecord));
  328.         {Go forward again through valid handles, saving them}
  329.         inc(H1, Delta);
  330.         H := 0;
  331.         while H1 <> H0 do begin
  332.           Status := GetHandleInfo(H1, LockCount, HandlesLeft, HMem);
  333.           if Status = 0 then begin
  334.             inc(H);
  335.             with XmsPages^[H] do begin
  336.               Handle := H1;
  337.               NumPages := HMem;
  338.             end;
  339.           end;
  340.           inc(H1, Delta);
  341.         end;
  342.         GetXmsHandles := HCnt;
  343.       end;
  344.  
  345.       {Deallocate dummy handle}
  346.       Status := FreeExtMem(H0);
  347.     end;
  348.   end;
  349.  
  350.   function DosVersion : Byte; Assembler;
  351.     {-Return major DOS version number}
  352.   asm
  353.     mov     ah,$30
  354.     int     $21
  355.   end;
  356.  
  357.   function ExtMemPossible : Boolean;
  358.     {-Return true if raw extended memory is possible}
  359.   const
  360.     ATclass = $FC;              {machine ID bytes}
  361.     Model80 = $F8;
  362.   var
  363.     MachineId : Byte absolute $FFFF : $000E;
  364.   begin
  365.     {don't allow allocation if running PC or XT, or under DOS 2.x or OS/2}
  366.     ExtMemPossible := False;
  367.     case DosVersion of
  368.       3..5 :
  369.         case MachineId of
  370.           ATclass, Model80 : ExtMemPossible := True;
  371.         end;
  372.     end;
  373.   end;
  374.  
  375.   function ExtMemTotalPrim : LongInt; assembler;
  376.     {-Returns total number of bytes of extended memory in the system}
  377.   asm
  378.     mov ah,$88
  379.     int $15
  380.     mov cx,1024
  381.     mul cx
  382.   end;
  383.  
  384. begin
  385.   if XmsInstalledPrim then
  386.     XmsControl := XmsControlAddr
  387.   else
  388.     XmsControl := nil;
  389. end.
  390.